package com.ikangtai.shecare.personal;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.ikangtai.shecare.R;
import com.ikangtai.shecare.common.App;
import com.ikangtai.shecare.common.BaseActivity;
import com.ikangtai.shecare.common.baseView.ListBar;
import com.ikangtai.shecare.common.baseView.TopBar;
import com.ikangtai.shecare.common.db.DBManager;
import com.ikangtai.shecare.common.db.sync.SyncMACAddressForUnbind;
import com.ikangtai.shecare.common.eventBusMsg.ConnectStateMsg;
import com.ikangtai.shecare.common.eventBusMsg.MyDeviceMsg;
import com.ikangtai.shecare.common.eventBusMsg.sync.SyncMACAddressForUnbindMsg;
import com.ikangtai.shecare.common.services.ble.BLEThermometerService;
import com.ikangtai.shecare.common.util.ActivityCollector;
import com.ikangtai.shecare.common.util.AppLog;
import com.ikangtai.shecare.common.util.Conversion;
import com.ikangtai.shecare.common.util.DeviceInfo;
import com.ikangtai.shecare.common.util.InternetUtil;
import com.ikangtai.shecare.common.util.OKHttpUtil;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;

import org.json.JSONException;
import org.json.JSONObject;
import org.simple.eventbus.EventBus;
import org.simple.eventbus.Subcriber;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Timer;
import java.util.TimerTask;


public class MyDeviceActivity extends BaseActivity implements View.OnClickListener {

    private TopBar topBar;
    private ListBar oad;
    private ListBar macAddress;
    private ListBar bindDevice;
    private ListBar unbindDevice;
    private ListBar lastConnectTime;
    private ListBar operation_guide_settings;
    private DBManager dbManager;
    private String firmwareVersion;
    private String imageFileUrl;
    private String currentFirmwareVersion;
    private int imageRevision;
    private InputStream inputStream = null;

    private boolean sign = false;
    private static BLEThermometerService mBLEThermometerService = null;
    private static boolean mScanning;
    private final long SCAN_PERIOD = 5000L;
    private BluetoothDevice mDevice = null;
    private static String action;
    private int scanSign = 0;
    private boolean mConnected = false;// 连接
    private int readnum_flag1 = 0;
    public final String DATABASE = "Database";
    private int THERMOMETER_CONNECTED_NUM = 0;
    private int THERMOMETER_CONNECTED_END_NUM = 0;
    private boolean isBLERegistered = false;

    private static final int GET_FIRMWARE_INFO_OK = 6;
    private static final int GET_FIRMWARE_INFO_NOK = 5;
    private static final int DOWNLOAD_IMAGE_FILE_OK = 7;

    // Programming parameters
    public static final short OAD_CONN_INTERVAL = 12; // 12.5 msec
    public static final short OAD_SUPERVISION_TIMEOUT = 100; // 1 second
    private static final int PKT_INTERVAL = 20; // Milliseconds
    private static final int GATT_WRITE_TIMEOUT = 100; // Milliseconds
    private static final int FILE_BUFFER_SIZE = 0x40000;
    private static final String FW_FILE_A = "Athermometer.bin";
    private static final String FW_FILE_B = "Bthermometer.bin";
    private static final int OAD_BLOCK_SIZE = 16;
    private static final int HAL_FLASH_WORD_SIZE = 4;
    private static final int OAD_BUFFER_SIZE = 2 + OAD_BLOCK_SIZE;
    private static final int OAD_IMG_HDR_SIZE = 8;

    // Programming entity
    private final byte[] mFileBuffer = new byte[FILE_BUFFER_SIZE];
    private final byte[] mOadBuffer = new byte[OAD_BUFFER_SIZE];
    private ImgHdr mFileImgHdr = new ImgHdr();
    private ImgHdr mTargImgHdr = new ImgHdr();
    private Timer mTimer = null;
    private ProgInfo mProgInfo = new ProgInfo();
    private TimerTask mTimerTask = null;
    private TextView mProgressInfo;
    private ProgressBar mProgressBar;
    private boolean mProgramming = false;
    private int mEstDuration = 0;
    private DeviceInfo deviceInfo;
    private boolean isActivityShown = false;
    private ProgressDialog progressDialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_my_device);
        ActivityCollector.addActivity(this);
        EventBus.getDefault().register(this);
        App.isMyDeviceActivityActive = true;
        findViewById(R.id.bindDevice).setOnClickListener(this);
        dbManager = new DBManager(this);
        deviceInfo = new DeviceInfo(this);
        initView();
        initBluetooth();
    }

    private void initView() {
        topBar = (TopBar) findViewById(R.id.topBar);
        topBar.setOnTopBarClickListener(new TopBar.OnTopBarClickListener() {
            @Override
            public void leftClick() {
                finish();
            }

            @Override
            public void midLeftClick() {

            }

            @Override
            public void midRightClick() {

            }

            @Override
            public void rightClick() {

            }
        });
        operation_guide_settings = (ListBar) findViewById(R.id.operation_guide_settings);
        operation_guide_settings.setOnClickListener(this);
        oad = (ListBar) findViewById(R.id.oad);
        oad.setOnClickListener(this);
        oad.setVisibility(View.GONE);
        macAddress = (ListBar) findViewById(R.id.macAddress);
        unbindDevice = (ListBar) findViewById(R.id.unbindDevice);
        unbindDevice.setOnClickListener(this);
        unbindDevice.setVisibility(View.GONE);
        bindDevice = (ListBar) findViewById(R.id.bindDevice);
        lastConnectTime = (ListBar) findViewById(R.id.lastConnTime);
        mProgressInfo = (TextView) findViewById(R.id.tw_info);
        mProgressBar = (ProgressBar) findViewById(R.id.pb_progress);
    }

    @Override
    protected void onResume() {
        super.onResume();
        isActivityShown = true;
        macAddress.setRightText(App.memory_preference_macAddress);
        if (null != App.memory_preference_macAddress) {
            unbindDevice.setVisibility(View.VISIBLE);
            bindDevice.setVisibility(View.GONE);
        }else{
            bindDevice.setVisibility(View.VISIBLE);
            unbindDevice.setVisibility(View.GONE);
        }
        if (null != App.memory_preference_lastConnectTime) {
            lastConnectTime.setRightText(App.memory_preference_lastConnectTime);
        }

        THERMOMETER_CONNECTED_NUM = 0;
        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
        //adapter不等于null，说明本机有蓝牙设备
        if (adapter != null) {
            AppLog.e("本机有蓝牙设备！");
            //如果蓝牙设备未开启
            if (adapter.isEnabled()) {
                if (mBLEThermometerService != null) {
                    operateThermometerScan(true);// 温度计扫描操作开始
                }
            } else {
            }
        }
        registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter());
        isBLERegistered = true;
    }

    @Override
    protected void onPause() {
        super.onPause();
        isActivityShown = false;
        THERMOMETER_CONNECTED_NUM = 0;
        AppLog.e("onPause");

        mBLEThermometerService.stopScanThermometers(mLeScanCallback);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.oad:
                checkFirmwareVersion();
//                Intent oadIntent = new Intent(this, OADMainActivity.class);
//                startActivity(oadIntent);
                break;
            case R.id.unbindDevice:
                if(ClickFilter.filter()) return;
                new AlertDialog.Builder(this)
                        .setTitle(getString(R.string.warm_prompt))
                        .setMessage(R.string.link_toast)
                        .setPositiveButton(R.string.sure, new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                showProgressDialog();
                                syncMACAddressAndUnbind();
                            }
                        })
                        .setNegativeButton(R.string.cancel, null)
                        .create()
                        .show();
                break;
            case R.id.bindDevice:
                Intent bindIntent = new Intent(this, MyDeviceChooseActivity.class);
                bindIntent.putExtra("type", "bindThermometer");
                startActivity(bindIntent);
                break;
            case R.id.operation_guide_settings:
                Intent guideIntent = new Intent(this, GuideImgActivity.class);
                startActivity(guideIntent);
                break;
        }
    }

    private void showProgressDialog() {
        progressDialog = new ProgressDialog(this);
        progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        progressDialog.setMessage(getString(R.string.unattch_in_process));
        progressDialog.setIndeterminate(false);
        progressDialog.setCancelable(false);
        progressDialog.show();
    }
    private void checkFirmwareVersion() {
        if (mConnected == false)
            Toast.makeText(MyDeviceActivity.this, R.string.not_link_hardware, Toast.LENGTH_SHORT).show();
        else {
            getLatestVersion();
        }

    }

    private void getLatestVersion() {
        OKHttpUtil okHttpClient = new OKHttpUtil(this);
        String appendUrl = "product/checkingFirmwareVersion.json?firmware=1";
        if(currentFirmwareVersion.startsWith("2")){
            appendUrl = "product/checkingFirmwareVersion.json?firmware=2";
        }

        okHttpClient.getAsync(appendUrl, okHttpClient.new BaseCallBack() {

            @Override
            public void onFailure(Request request, IOException e) {
                super.onFailure(request, e);
            }

            @Override
            public void onResponse(Response response) throws IOException {

                try {
                    JSONObject respJSONObj = new JSONObject(response.body().string());
                    int respCode = respJSONObj.getInt("code");
                    AppLog.e("" + respCode);
                    if (App.HTTP_RESP_OK == respCode) {
                        firmwareVersion = respJSONObj.getString("version");
                        imageFileUrl = respJSONObj.getString("fileURL");
                        MyDeviceMsg myDeviceMsg = new MyDeviceMsg();
                        myDeviceMsg.setRespCode(GET_FIRMWARE_INFO_OK);
                        EventBus.getDefault().post(myDeviceMsg);

                    } else {
                        MyDeviceMsg myDeviceMsg = new MyDeviceMsg();
                        myDeviceMsg.setRespCode(GET_FIRMWARE_INFO_NOK);
                        EventBus.getDefault().post(myDeviceMsg);

                    }
                } catch (JSONException e) {

                    e.printStackTrace();
                }
            }
        });
    }

    private void syncMACAddressAndUnbind() {
        if (InternetUtil.hasInternet()) {
            SyncMACAddressForUnbindMsg SyncMACAddressForUnbindMsg = new SyncMACAddressForUnbindMsg();
            SyncMACAddressForUnbindMsg.setMacAddress(App.memory_preference_macAddress);
            SyncMACAddressForUnbindMsg.setOSType(deviceInfo.getPhoneVersion());
            SyncMACAddressForUnbind syncMACAddressForUnbind = new SyncMACAddressForUnbind(this, SyncMACAddressForUnbindMsg);
            syncMACAddressForUnbind.syncMACAddressForUnbindWithNetwork();
        } else {
            MyDeviceMsg myDeviceMsg = new MyDeviceMsg();
            myDeviceMsg.setRespCode(App.HTTP_RESP_FAIL);
            EventBus.getDefault().post(myDeviceMsg);
            Toast.makeText(this, R.string.network_anomalies, Toast.LENGTH_SHORT).show();
        }
    }

    private void unbindDevice() {
        AppLog.i("MyDeviceActivity 准备unbindDevice()！");

        OKHttpUtil okHttpClient = new OKHttpUtil(this);
        String appendUrl = "hardware/unbindingThermometer.json";
        try {
            okHttpClient.add("authToken", App.authToken);
            okHttpClient.add("MACAddress", App.memory_preference_macAddress);
            okHttpClient.postAsync(appendUrl, okHttpClient.new BaseCallBack() {

                @Override
                public void onFailure(Request request, IOException e) {
                    MyDeviceMsg myDeviceMsg = new MyDeviceMsg();
                    myDeviceMsg.setRespCode(App.HTTP_RESP_FAIL);
                    EventBus.getDefault().post(myDeviceMsg);

                    super.onFailure(request, e);
                }

                @Override
                public void onResponse(Response response) throws IOException {
                    MyDeviceMsg myDeviceMsg = new MyDeviceMsg();
                    try {
                        JSONObject respJSONObj = new JSONObject(response.body().string());
                        int respCode = respJSONObj.getInt("code");
                        AppLog.i("response code:" + respCode);
                        if (200 == respCode) {
                            myDeviceMsg.setRespCode(App.HTTP_RESP_OK);
                        } else if (respCode == App.HTTP_RESP_TOKEN_TIME_OUT) {
                            OKHttpUtil.setNewToken();
                            myDeviceMsg.setRespCode(App.HTTP_RESP_TOKEN_TIME_OUT);
                        } else {
                            myDeviceMsg.setRespCode(App.HTTP_RESP_FAIL);
                        }
                    } catch (JSONException e) {
                        myDeviceMsg.setRespCode(App.HTTP_RESP_FAIL);
                        AppLog.i("upload registerUserInfo onResponse failed!");
                        e.printStackTrace();
                    }
                    EventBus.getDefault().post(myDeviceMsg);
                }
            });
        } catch (JSONException e) {
            MyDeviceMsg myDeviceMsg = new MyDeviceMsg();
            myDeviceMsg.setRespCode(App.HTTP_RESP_FAIL);
            EventBus.getDefault().post(myDeviceMsg);
            e.printStackTrace();
        }

    }

    @Subcriber
    private void syncMACAddressForUnbind(SyncMACAddressForUnbindMsg syncMACAddressForUnbindMsg) {
        unbindDevice();
    }

    @Subcriber
    private void dealMyDeviceMsg(MyDeviceMsg myDeviceMsg) {
        int respCode = myDeviceMsg.getRespCode();
        switch (respCode) {

            case App.HTTP_RESP_OK:
                progressDialog.setMessage(getString(R.string.unattch_success));
                //Toast.makeText(getApplicationContext(), R.string.unattch_success, Toast.LENGTH_SHORT).show();
                dbManager.updateUserPreference(App.userName, "macAddress", null, "isMACAddressSynced", 1);
                App.memory_preference_macAddress = null;
                unbindDevice.setVisibility(View.GONE);
                bindDevice.setVisibility(View.VISIBLE);
                macAddress.setRightText("");
                ConnectStateMsg connectStateMsg = new ConnectStateMsg();
                connectStateMsg.setRespCode(2);
                EventBus.getDefault().post(connectStateMsg);
                (new Handler()).postDelayed(new Runnable() {
                    @Override
                    public synchronized void run() {
                        AppLog.i("MyDeviceActivity 解绑成功之后1.5s，需要dismiss掉dialog");
                        if (progressDialog != null && progressDialog.isShowing()) {
                            AppLog.i("MyDeviceActivity 解绑成功之后1.5s，dismiss掉dialog了！");
                            progressDialog.dismiss();
                            progressDialog = null;
                        }
                    }
                }, 1500);
                break;

            case App.HTTP_RESP_FAIL:
                progressDialog.setMessage(getString(R.string.unattch_failure));
                dbManager.updateUserPreference(App.userName, "macAddress", App.memory_preference_macAddress, "isMACAddressSynced", 0);
                //Toast.makeText(getApplicationContext(), "解绑失败!", Toast.LENGTH_SHORT).show();
                (new Handler()).postDelayed(new Runnable() {
                    @Override
                    public synchronized void run() {
                        AppLog.i("MyDeviceActivity 解绑失败之后1.5s，需要dismiss掉dialog");
                        if (progressDialog != null && progressDialog.isShowing()) {
                            AppLog.i("MyDeviceActivity 解绑失败之后1.5s，dismiss掉dialog了！");
                            progressDialog.dismiss();
                            progressDialog = null;
                        }
                    }
                }, 1500);
                break;
            case App.LAST_CONNECT_TIME:
                lastConnectTime.setRightText(App.memory_preference_lastConnectTime);
                break;
            case GET_FIRMWARE_INFO_OK:
                if (currentFirmwareVersion.startsWith("2") && !firmwareVersion.equals(currentFirmwareVersion)) {
                    Dialog alertDialog = new AlertDialog.Builder(this).
                            setTitle(R.string.warm_prompt).
                            setMessage(R.string.update_share_hardware).
                            setPositiveButton(R.string.sure, new DialogInterface.OnClickListener() {

                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    updateProgram();
                                    dialog.dismiss();
                                }
                            }).
                            create();
                    alertDialog.setCancelable(false);
                    alertDialog.show();
                } else if (currentFirmwareVersion.startsWith("2") && firmwareVersion.equals(currentFirmwareVersion)) {
                    Dialog alertDialog = new AlertDialog.Builder(this).
                            setTitle(R.string.warm_prompt).
                            setMessage(R.string.share_hardware_newest).
                            setPositiveButton(R.string.sure, new DialogInterface.OnClickListener() {

                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    updateProgram();
                                    dialog.dismiss();
                                }
                            }).
                            create();
                    alertDialog.setCancelable(false);
                    alertDialog.show();
                } else if (currentFirmwareVersion.startsWith("1")) {
                    Dialog alertDialog = new AlertDialog.Builder(this).
                            setTitle(R.string.warm_prompt).
                            setMessage(R.string.share_hardware_newest).
                            setPositiveButton(R.string.sure, new DialogInterface.OnClickListener() {

                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    updateProgram();
                                    dialog.dismiss();
                                }
                            }).
                            create();
                    alertDialog.setCancelable(false);
                    alertDialog.show();
                }
                break;
            case GET_FIRMWARE_INFO_NOK:
                break;
            case DOWNLOAD_IMAGE_FILE_OK:
                startProgramming();
                break;
            case App.HTTP_RESP_TOKEN_TIME_OUT:
                unbindDevice();
                break;
            default:
                break;
        }

    }

    private void startProgramming() {
        (new Handler()).postDelayed(new Runnable() {
            @Override
            public synchronized void run() {

                mProgramming = true;
                mProgressInfo.setVisibility(View.VISIBLE);
                mProgressBar.setVisibility(View.VISIBLE);
                // Expected duration
                mEstDuration = ((PKT_INTERVAL * mFileImgHdr.len * 4) / OAD_BLOCK_SIZE) / 1000;
                displayStats();
                // Prepare image notification
                byte[] buf = new byte[OAD_IMG_HDR_SIZE + 2 + 2];
                buf[0] = Conversion.loUint16(mFileImgHdr.ver);
                buf[1] = Conversion.hiUint16(mFileImgHdr.ver);
                buf[2] = Conversion.loUint16(mFileImgHdr.len);
                buf[3] = Conversion.hiUint16(mFileImgHdr.len);
                System.arraycopy(mFileImgHdr.uid, 0, buf, 4, 4);
                buf[OAD_IMG_HDR_SIZE + 0] = Conversion.loUint16((short) 12);
                buf[OAD_IMG_HDR_SIZE + 1] = Conversion.hiUint16((short) 12);
                buf[OAD_IMG_HDR_SIZE + 2] = Conversion.loUint16((short) 15);
                buf[OAD_IMG_HDR_SIZE + 1] = Conversion.hiUint16((short) 15);
                mBLEThermometerService.writeOADImageValue(buf);

                // Initialize stats
                mProgInfo.reset();
                // Start the packet timer
                mTimer = null;
                mTimer = new Timer();
                mTimerTask = new ProgTimerTask();
                mTimer.scheduleAtFixedRate(mTimerTask, 400, PKT_INTERVAL);

            }
        }, 200);
    }

    private void updateProgram() {
        // Change connection parameters for OAD
        mBLEThermometerService.setConnectionParameters();

        (new Handler()).postDelayed(new Runnable() {
            @Override
            public synchronized void run() {
                mBLEThermometerService.notifyOADStart();
                final String downUrl;
                if (imageRevision == 0) downUrl = imageFileUrl + "/" + FW_FILE_A;
                else downUrl = imageFileUrl + "/" + FW_FILE_B;
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            inputStream = getInputStreamFromUrl(downUrl);
                            inputStream.read(mFileBuffer, 0, mFileBuffer.length);
                            int n = mFileBuffer.length;
                            inputStream.close();
                            // Show image info
                            mFileImgHdr.ver = Conversion.buildUint16(mFileBuffer[5], mFileBuffer[4]);
                            mFileImgHdr.len = Conversion.buildUint16(mFileBuffer[7], mFileBuffer[6]);
                            AppLog.e("mFileImgHdr.ver" + mFileImgHdr.ver + "mFileImgHdr.len" + mFileImgHdr.len);
                            mFileImgHdr.imgType = ((mFileImgHdr.ver & 1) == 1) ? 'B' : 'A';
                            System.arraycopy(mFileBuffer, 8, mFileImgHdr.uid, 0, 4);
                            MyDeviceMsg myDeviceMsg = new MyDeviceMsg();
                            myDeviceMsg.setRespCode(DOWNLOAD_IMAGE_FILE_OK);
                            EventBus.getDefault().post(myDeviceMsg);
                            return;

                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }).start();

            }
        }, 200);

//        Intent intent = new Intent(MyDeviceActivity.this, OADMainActivity.class);
//        intent.putExtra("fileURL", imageFileUrl);
//        startActivity(intent);
    }

    private void setConnectionParameters() {
        // Make sure connection interval is long enough for OAD
        byte[] value = {Conversion.loUint16(OAD_CONN_INTERVAL), Conversion.hiUint16(OAD_CONN_INTERVAL), Conversion.loUint16(OAD_CONN_INTERVAL),
                Conversion.hiUint16(OAD_CONN_INTERVAL), 0, 0, Conversion.loUint16(OAD_SUPERVISION_TIMEOUT), Conversion.hiUint16(OAD_SUPERVISION_TIMEOUT)};
        boolean result = mBLEThermometerService.writeOADImageRequestValue(value);
        AppLog.e("setConnectionParameters:" + result);
    }

    private class ProgTimerTask extends TimerTask {
        @Override
        public void run() {
            mProgInfo.mTick++;
            if (mProgramming) {
                onBlockTimer();
                if ((mProgInfo.mTick % PKT_INTERVAL) == 0) {
                    runOnUiThread(new Runnable() {
                        public void run() {
                            displayStats();
                        }
                    });
                }
            }
        }
    }

    private void displayStats() {
        String txt;
        int byteRate;
        int sec = mProgInfo.iTimeElapsed / 1000;
        if (sec > 0) {
            byteRate = mProgInfo.iBytes / sec;
        } else {
            byteRate = 0;
        }

        txt = String.format("Time: %d / %d sec", sec, mEstDuration);
        txt += String.format("    Bytes: %d (%d/sec)", mProgInfo.iBytes, byteRate);
        mProgressInfo.setText(txt);
    }

      /*
   * Called when a notification with the current image info has been received
   */

    private void onBlockTimer() {

        if (mProgInfo.iBlocks < mProgInfo.nBlocks) {
            mProgramming = true;

            // Prepare block
            mOadBuffer[0] = Conversion.loUint16(mProgInfo.iBlocks);
            mOadBuffer[1] = Conversion.hiUint16(mProgInfo.iBlocks);
            System.arraycopy(mFileBuffer, mProgInfo.iBytes, mOadBuffer, 2, OAD_BLOCK_SIZE);

            // Send block
            boolean success = mBLEThermometerService.writeOADImageRequestValue(mOadBuffer);

            if (success) {
                // Update stats
                mProgInfo.iBlocks++;
                mProgInfo.iBytes += OAD_BLOCK_SIZE;
                mProgressBar.setProgress((mProgInfo.iBlocks * 100) / mProgInfo.nBlocks);
                AppLog.e("iBlocks" + mProgInfo.iBlocks);
            } else {
                // Check if the device has been prematurely disconnected
                if (mBLEThermometerService == null)
                    mProgramming = false;
            }
        } else {
            mProgramming = false;
        }
        mProgInfo.iTimeElapsed += PKT_INTERVAL;

        if (!mProgramming) {
            runOnUiThread(new Runnable() {
                public void run() {
                    displayStats();
                    stopProgramming();
                }
            });
        }
    }

    private void stopProgramming() {
        mTimer.cancel();
        mTimer.purge();
        mTimerTask.cancel();
        mTimerTask = null;

        mProgramming = false;
        mProgressInfo.setText("");
        mProgressInfo.setVisibility(View.GONE);
        mProgressBar.setVisibility(View.GONE);
        mProgressBar.setProgress(0);

        if (mProgInfo.iBlocks == mProgInfo.nBlocks) {
            AppLog.e("Programming complete!");
        }
    }

    //根据URL得到输入流
    private InputStream getInputStreamFromUrl(String urlStr) throws MalformedURLException, IOException {
        // TODO Auto-generated method stub

        URL url = new URL(urlStr);
        HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
        InputStream inputStream = urlConn.getInputStream();
        return inputStream;
    }

    private void initBluetooth() {
        // 绑定服务
        Intent gattServiceIntent = new Intent(MyDeviceActivity.this, BLEThermometerService.class);
        sign = getApplicationContext().bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE);
    }

    private final ServiceConnection mServiceConnection = new ServiceConnection() {

        @SuppressLint("NewApi")
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder service) {
            AppLog.e("CalendarActivity onServiceConnected");
            mBLEThermometerService = ((BLEThermometerService.LocalBinder) service).getService();
            // initialize初始化
            if (!mBLEThermometerService.initialize()) {// 如果温度计服务不初始化
                Toast.makeText(MyDeviceActivity.this, R.string.bluetooth_unused, Toast.LENGTH_SHORT).show();
            } else {
                mBLEThermometerService.openBluetooth(MyDeviceActivity.this);
                if (BluetoothAdapter.getDefaultAdapter().isEnabled())
                    operateThermometerScan(true);// 温度计扫描操作打开
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            mBLEThermometerService = null;
        }
    };

    // 温度计扫描操作
    private void operateThermometerScan(final boolean enable) {
        AppLog.e("ThermometerService come in operateThermometerScan");
        if (mBLEThermometerService == null) {// 如果蓝牙温度计服务没有被绑定，就提示
            Toast.makeText(this, R.string.bluetooth_init, Toast.LENGTH_SHORT).show();
            return;
        }

        if (enable) {
            AppLog.e("CalendarActivity begin operateThermometerScan");
            if (mBLEThermometerService.thermometers.size() == 0) {
                mScanning = mBLEThermometerService.scanThermometers(mLeScanCallback);
            }
        } else {
            mScanning = false;
            mBLEThermometerService.stopScanThermometers(mLeScanCallback); // 停止扫描温度计
        }
    }

    @SuppressLint("NewApi")
    private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {

        @Override
        public void onLeScan(final BluetoothDevice device, int rssi,
                             byte[] scanRecord) {
            int i = 0;
            String address = device.getAddress();
            if (null != App.memory_preference_macAddress && address.equals(App.memory_preference_macAddress)) {
                AppLog.e("CalendarActivity LeScanCallback ThermometerSensor0");
                mBLEThermometerService.thermometers.add(device);

                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        if ((mBLEThermometerService.autoConnect)
                                && (mBLEThermometerService.thermometers.size() > 0)) {
                            mBLEThermometerService.stopScanThermometers(mLeScanCallback);
                            mDevice = BluetoothAdapter.getDefaultAdapter()
                                    .getRemoteDevice(device.getAddress());
                            AppLog.e("CalendarActivity LeScanCallback connectThermometer");
                            mBLEThermometerService.connectThermometer(mDevice
                                    .getAddress());
                        }
                    }
                });
            }
        }
    };

    private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {

            action = intent.getAction();
            AppLog.e("onReceive action=" + action);
            if (BLEThermometerService.ThermometerMessage.THERMOMETER_FOUND.getName().equals(action)) {// 如果找到温度计的信息与程序定义的温度计信息一致
            }
            if (BLEThermometerService.ThermometerMessage.THERMOMETER_CONNECTED.getName().equals(action)) {// 连接成功

            } else if (BLEThermometerService.ThermometerMessage.THERMOMETER_DISCONNECTED.getName()
                    .equals(action)) {// 断开连接温度计
                AppLog.e("THERMOMETER_DISCONNECTED");
                updateDisconnectInfo();
            } else if (BLEThermometerService.ThermometerMessage.FIRMWARE_TIMESYNC_FOUND.getName()
                    .equals(action)) {

            } else if (BLEThermometerService.ThermometerMessage.CLOSE_THERMOMETER_FOUND.getName()
                    .equals(action)) {

            } else if (BLEThermometerService.ThermometerMessage.TEMPERATURE_MEASUREMENT_OPEN.getName()
                    .equals(action)) {
                AppLog.e("TEMPERATURE_MEASUREMENT_OPEN");
                if(isActivityShown){
                    mBLEThermometerService.readFirmwareRevision();
                    (new Handler()).postDelayed(new Runnable() {
                        @Override
                        public synchronized void run() {
                            mBLEThermometerService.writeOADImageRevision();
                        }
                    }, 200);
                }
            } else if (BLEThermometerService.ThermometerMessage.BIND_PHONE_FOUND.getName()
                    .equals(action)) {
//                handleBindPhoneResult(intent);
            } else if (BLEThermometerService.ThermometerMessage.FIRMWARE_REVISION_READ.getName().equals(action)) {
                updateConnectInfo();
                String hardwareVersion = intent.getStringExtra(BLEThermometerService.ThermometerDataTag.FIRMWARE_REVISION_DATA.getName());
                AppLog.e("HARDWARE_REVISION_READ" + hardwareVersion);
                currentFirmwareVersion = hardwareVersion;
                App.saveUserPreference("hardwareRevision", App.hardwareRevision);
            } else if (BLEThermometerService.ThermometerMessage.OAD_IMAGE_REVISION_READ.getName().equals(action)) {
                imageRevision = intent.getIntExtra(BLEThermometerService.ThermometerDataTag.OAD_IMAGE_REVISION_DATA.getName(), 0);
                AppLog.e("OAD_IMAGE_REVISION_DATA" + imageRevision);
            } else if (BLEThermometerService.ThermometerMessage.MEASUREMENT_INTERVAL_FOUND.getName()
                    .equals(action)) {
                AppLog.e("MEASUREMENT_INTERVAL_FOUND");
            } else if (BLEThermometerService.ThermometerMessage.TEMPERATURE_MEASUREMENT_READ.getName()
                    .equals(action)) {

            } else if (BLEThermometerService.ThermometerMessage.INTERMEDIATE_TEMPERATURE_READ
                    .getName().equals(action)) {
                //operateThermometerScan(true);
            }

        }

        private void updateDisconnectInfo() {
            mConnected = false;
            THERMOMETER_CONNECTED_NUM = 0;
            THERMOMETER_CONNECTED_END_NUM = 0;
            if(isActivityShown){
                if (scanSign == 0) {
                    scanSign = 1;
                    (new Handler()).postDelayed(new Runnable() {
                        @Override
                        public synchronized void run() {
                            scanSign = 0;
                            operateThermometerScan(true);// 温度计扫描操作打开
                        }
                    }, SCAN_PERIOD);
                    AppLog.e("THERMOMETER_DISCONNECTED postDelayed operateThermometerScan");
                }
            }
        }

        private void updateConnectInfo() {
            mConnected = true;
            if (THERMOMETER_CONNECTED_NUM == 0) {
                 //Toast.makeText(MyDeviceActivity.this, "可以进行设备程序升级", Toast.LENGTH_SHORT).show();

                THERMOMETER_CONNECTED_NUM = THERMOMETER_CONNECTED_NUM + 1;
            } else {
                THERMOMETER_CONNECTED_NUM = THERMOMETER_CONNECTED_NUM + 1;
            }
        }
    };

    private IntentFilter makeGattUpdateIntentFilter() {
        final IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(BLEThermometerService.ThermometerMessage.THERMOMETER_FOUND.getName());
        intentFilter.addAction(BLEThermometerService.ThermometerMessage.THERMOMETER_CONNECTED
                .getName());
        intentFilter.addAction(BLEThermometerService.ThermometerMessage.THERMOMETER_DISCONNECTED
                .getName());
        intentFilter
                .addAction(BLEThermometerService.ThermometerMessage.RSSI_DATA_AVAILABLE.getName());
        intentFilter.addAction(BLEThermometerService.ThermometerMessage.TEMPERATURE_MEASUREMENT_OPEN
                .getName());
        intentFilter.addAction(BLEThermometerService.ThermometerMessage.INTERMEDIATE_TEMPERATURE_OPEN
                .getName());
        intentFilter.addAction(BLEThermometerService.ThermometerMessage.TEMPERATURE_MEASUREMENT_READ
                .getName());
        intentFilter.addAction(BLEThermometerService.ThermometerMessage.INTERMEDIATE_TEMPERATURE_READ
                .getName());
        intentFilter.addAction(BLEThermometerService.ThermometerMessage.HARDWARE_REVISION_READ
                .getName());
        intentFilter.addAction(BLEThermometerService.ThermometerMessage.BIND_PHONE_FOUND
                .getName());
        intentFilter.addAction(BLEThermometerService.ThermometerMessage.FIRMWARE_TIMESYNC_FOUND
                .getName());
        intentFilter.addAction(BLEThermometerService.ThermometerMessage.FIRMWARE_REVISION_READ
                .getName());
        intentFilter.addAction(BLEThermometerService.ThermometerMessage.CLOSE_THERMOMETER_FOUND
                .getName());
        intentFilter.addAction(BLEThermometerService.ThermometerMessage.OAD_IMAGE_REVISION_READ
                .getName());
        return intentFilter;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
        AppLog.e("-----onDestroy");
        App.isMyDeviceActivityActive = false;
        if (mTimerTask != null)
            mTimerTask.cancel();
        if (mTimer != null)
            mTimer = null;
        operateThermometerScan(false);// 温度计扫描操作停止
        if (mGattUpdateReceiver != null && isBLERegistered == true) {
            unregisterReceiver(mGattUpdateReceiver);// 不注册广播接收器
            isBLERegistered = false;
        }
        if (sign && mServiceConnection != null) {
            getApplicationContext().unbindService(mServiceConnection);//解绑服务
            AppLog.e("onDestroy unbindService");
            sign = false;
        }
        getApplicationContext().stopService(new Intent(MyDeviceActivity.this, BLEThermometerService.class));
        ActivityCollector.removeActivity(this);
    }


    private class ImgHdr {
        short ver;
        short len;
        Character imgType;
        byte[] uid = new byte[4];
    }

    private class ProgInfo {
        int iBytes = 0; // Number of bytes programmed
        short iBlocks = 0; // Number of blocks programmed
        short nBlocks = 0; // Total number of blocks
        int iTimeElapsed = 0; // Time elapsed in milliseconds
        int mTick = 0;

        void reset() {
            iBytes = 0;
            iBlocks = 0;
            iTimeElapsed = 0;
            mTick = 0;
            nBlocks = (short) (mFileImgHdr.len / (OAD_BLOCK_SIZE / HAL_FLASH_WORD_SIZE));
        }
    }

    public static class ClickFilter
    {
        public static final long INTERVAL = 500L; //防止连续点击的时间间隔
        private static long lastClickTime = 0L; //上一次点击的时间

        public static boolean filter()
        {
            long time = System.currentTimeMillis();

            if ( ( time - lastClickTime ) > INTERVAL )
            {
                lastClickTime = time;
                return false;
            }
            return true;
        }
    }

}
